﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Text.RegularExpressions;

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service" in code, svc and config file together.
public class WordFilter : IService
{
    private string _text;
    private string _filteredText;

    /// <summary>
    /// Word Filter constructor.
    /// </summary>
    public WordFilter()
    {
        this._text = "";
        this._filteredText = "";
    }    

    public string FilterButLeaveStopWords(string text)
    {
        this._text = text;
        this.runFilter(false);
        return this._filteredText;
    }

    public string FilterAndRemoveStopWords(string text)
    {
        this._text = text;
        this.runFilter(true);
        return this._filteredText;
    }

    /// <summary>
    /// Filters HTML to remove unwanted tags and words
    /// </summary>
    /// <param name="removeStopWords">Set to true in order to remove stop words as well</param>
    /// <returns>Filtered string</returns>
    private void runFilter(bool removeStopWords)
    {
        this._filteredText = this._text;
        
        string pattern = "";
        string replacement = " ";
        
        // Remove all of <script> contents since it is code, not content.
        this._filteredText = Regex.Replace(this._filteredText, "<script.*?</script>", replacement, RegexOptions.Singleline | RegexOptions.IgnoreCase);

        // Remove all of the <style> content since it is styling code.
        this._filteredText = Regex.Replace(this._filteredText, "<style.*?</style>", replacement, RegexOptions.Singleline | RegexOptions.IgnoreCase);
        
        // Remove tags
        pattern = @"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement, RegexOptions.Singleline | RegexOptions.IgnoreCase);

        // Remove left over tags that first pass missed
        pattern = @"<.*?>";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement, RegexOptions.Singleline | RegexOptions.IgnoreCase);

        // Replace HTML spaced entity with single space
        pattern = @"&nbsp;";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement);

        // Replace &amp; (&) with and
        pattern = @"&amp;";
        this._filteredText = Regex.Replace(this._filteredText, pattern, " and ");

        // Replace &#8217; with '
        pattern = @"&#8217;";
        this._filteredText = Regex.Replace(this._filteredText, pattern, "'");

        // Replace comma (,) with space
        pattern = @", ";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement);

        // Replace period+space (. ), question mark, exclamation mark with space
        pattern = @"\. |\?|\!";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement);

        // Replace any leftover HTML entities
        pattern = @"&.*?;";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement);

        // Replace mutliple spaces with single space between words
        pattern = @"\s+";
        this._filteredText = Regex.Replace(this._filteredText, pattern, replacement);

        // Remove stop words
        if (removeStopWords)
        {
            this.removeStopWords();
        }
    }

    /// <summary>
    /// Private method to remove stop words from text
    /// </summary>
    private void removeStopWords()
    {
        // open stopWords.txt file
        var serverPath = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/stopWords.txt");
        string text = System.IO.File.ReadAllText(serverPath);

        // put stop words into array
        string[] stopWords = text.Split(',');
        string replacement = " ";

        // Iterate through each stop word and remove from text
        foreach (string stopWord in stopWords)
        {
            string pattern = " " + stopWord + " ";
            this._filteredText = Regex.Replace(this._filteredText, pattern, replacement, RegexOptions.IgnoreCase);
        }
    }
}
